package com.gitee.fsmxm.thinking.in.concurrent.basic;

// 几种单例模式写法
public class _04_Singleton_Samples {
    
    // 1. 使用枚举类
    public enum SingletonByEnum {
        INSTANCE;

        public static SingletonByEnum getInstance() {
            return INSTANCE;
        }

        // 其他方法...
    }

    // 2. 饿汉式
    public static class SingletonByStaticInitialInstance {

        private static final SingletonByStaticInitialInstance INSTANCE = new SingletonByStaticInitialInstance();

        private SingletonByStaticInitialInstance() {
        }

        public static SingletonByStaticInitialInstance getInstance() {
            return INSTANCE;
        }

        // 其他方法...

    }

    // 3. 内部类方式
    public static class SingletonByStaticInnerClass {

        private SingletonByStaticInnerClass() {
        }

        public static SingletonByStaticInnerClass getInstance() {
            return SingletonHelper.INSTANCE;
        }

        private static class SingletonHelper {
            private static final SingletonByStaticInnerClass INSTANCE = new SingletonByStaticInnerClass();
        }

        // 其他方法...

    }

    // 4. 双重检查锁
    public static class SingletonByVolatileSynchronized {

        private SingletonByVolatileSynchronized() {
        }

        // volatile 保证instance初始化的顺序
        private static volatile SingletonByVolatileSynchronized instance;

        public static SingletonByVolatileSynchronized getInstance() {
            if (instance == null) {
                synchronized (SingletonByVolatileSynchronized.class) {
                    if (instance == null) {
                        instance = new SingletonByVolatileSynchronized();
                    }
                }
            }
            return instance;
        }

        // 其他方法...

    }

    public static void main(String[] args) {
        SingletonByEnum singleton1 = SingletonByEnum.INSTANCE;

        SingletonByStaticInitialInstance singleton2 = SingletonByStaticInitialInstance.getInstance();

        SingletonByStaticInnerClass singleton3 = SingletonByStaticInnerClass.getInstance();

        SingletonByVolatileSynchronized singleton4 = SingletonByVolatileSynchronized.getInstance();
    }
}
